<html>
<head>
<link rel="shortcut icon" href="./favicon.ico">
<link rel="stylesheet" type="text/css" href="./style.css">
<link rel="canonical" href="./CDC_Bit_Synchronizer.html">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="Use a synchronizer to convert changes in a signal in one clock domain into changes which are synchronous to another clock domain, while reducing the probability of metastable events propagating.">
<title>CDC Bit Synchronizer</title>
</head>
<body>

<p class="inline bordered"><b><a href="./CDC_Bit_Synchronizer.v">Source</a></b></p>
<p class="inline bordered"><b><a href="./legal.html">License</a></b></p>
<p class="inline bordered"><b><a href="./index.html">Index</a></b></p>

<h1>Clock Domain Crossing (CDC) Bit Synchronizer</h1>
<p>Use a synchronizer to convert changes in a signal in one clock domain into
 changes which are synchronous to another clock domain, while reducing the
 probability of metastable events propagating.</p>
<h2>A Warning</h2>
<p>A synchronizer is a trivial circuit, but it breaks the conventions of
 synchronous logic while doing its best to contain the consequences. Thus,
 it is very easy to use a synchronizer incorrectly, leading to worse timing
 closure at best, or at worst intermittent circuit malfunctions which won't
 be visible (or even reproducible!) in simulations. We go over the necessary
 subtleties in the text and code below.</p>
<h2>Relative Clock Frequency Constraints</h2>
<p>This synchronizer is the fundamental building block of all other CDC
 circuits, and it must be used under one major constraint to operate
 properly: Any change on the input signal must hold steady for a <strong>minimum</strong>
 of 1.5x longer than the period of the receiving clock to guarantee enough
 time for three receiving clock edges (posedge/negedge/posedge, or
 negedge/posedge/negedge) to pass, which guarantees that the input signal
 will be properly sampled by a posedge.</p>
<p>Any less time, and the input signal could change back before it was sampled
 by the receiving clock. In other words, assuming single-cycle changes
 (pulses), the receiving clock domain can have a clock frequency of at most
 0.66x that of the sending clock domain. For any higher receiving clock
 freqency, you must guarantee that the change on the input signal will last
 enough input clock cycles to be seen by at least three consecutive
 receiving clock edges.</p>
<p>If you cannot guarantee the duration of a pulse and/or have no knowledge of
 the relative clock domain frequencies, use a <a href="./CDC_Pulse_Synchronizer_2phase.html">Pulse
 Synchronizer</a>.</p>
<p>Similarly, if the rise/fall time of the input signal is longer than the
 receiving clock period, the receiving clock will sample the transistion
 multiple times, which will show up as possibly multiple pulses at the
 output. In these cases, use a <a href="./Debouncer_Low_Latency.html">Debouncer</a>.</p>
<h2>Single-Bit Synchronization Only</h2>
<p>Also, for reasons explained in <a href="./cdc.html">A Primer on Clock Domain Crossing
 Theory</a>, the latency of a CDC Synchronizer can vary between
 1 and 3 cycles, depending on clock phase and metastability events, and so
 <strong>only one signal may be synchronized at each clock domain crossing</strong>.
 Using multiple CDC Synchronizers in parallel is <strong>not deterministic</strong> as
 there is no guarantee they will all have the same latency.</p>
<p>If you need to pass multiple signals (e.g.: a bus), synchronize one signal
 in each direction as a ready/valid handshake, and capture the other signals
 (held steady during synchronization) directly in the receiving clock domain
 once the one signal has synchronized. Remember to constrain and check the
 delay on the other signals. The <a href="./CDC_Word_Synchronizer.html">CDC Data
 Synchronizer</a> implements this approach, and
 the <a href="./CDC_Pulse_Synchronizer_2phase.html">CDC Pulse Synchronizer</a> can also
 be used to build similar CDC circuits.</p>
<h2>Avoid Logic Glitches</h2>
<p><strong>You must feed a CDC Synchronizer directly from a register</strong>, with no
 logic between it and the synchronizer. Otherwise, it's possible that
 multiple logic paths will converge to the synchronizer, and convergent
 logic can glitch when signals change state (we're not getting into that
 theory here).  Normally, a subsequent register will filter out such
 glitches since they settle long before the next clock edge. However,
 a synchronizer's unrelated and asynchronous receiving clock may just happen
 to sample the input when a glitch occurs, transforming that glitch into
 a real, and completely wrong, logic pulse in the receiving clock domain!
 Alternately, a high signal may glitch early to low and be missed by the
 receiving clock.</p>
<h2>Not Usable as I/O Registers</h2>
<p>On an FPGA, you should not use an I/O register as one of the stages of
 a synchronizer: they are too far from the main logic fabric, and
 synchronizer registers must be as close together as possible (see <a href="./cdc.html">A Primer
 on Clock Domain Crossing Theory</a>). Thus, your input or output
 must connect to a dedicated I/O register synchronous to the I/O clock,
 which in turn connects to a CDC synchronizer driven by the internal clock.
 <strong>This extra I/O register also filters out any input glitches, as outlined
 above.</strong></p>

<pre>
`default_nettype none

module <a href="./CDC_Bit_Synchronizer.html">CDC_Bit_Synchronizer</a>
#(
    parameter EXTRA_DEPTH = 0 // Must be 0 or greater
)
(
    input   wire    receiving_clock,
    input   wire    bit_in,
    output  reg     bit_out
);
</pre>

<p>The minimum valid synchronizer depth is 2. Add more stages if the design
 requires it. This usually happens near the highest operating frequencies.
 Consult your device datasheets.</p>

<pre>
    localparam DEPTH = 2 + EXTRA_DEPTH;
</pre>

<p>For Vivado, we must specify that the synchronizer registers should be
 placed close together (see: UG912), and to show up as part of MTBF reports.</p>
<p>For Quartus, specify that these register must not be optimized (e.g. moved
 into the input register of a DSP or BRAM) and to mark them as composing
 a synchronizer (and so be placed close together).</p>
<p>In both cases, we also specify that the registers must not be placed in I/O
 register locations.</p>

<pre>
    // Vivado
    (* IOB = "false" *)
    (* ASYNC_REG = "TRUE" *)

    // Quartus
    (* useioff = 0 *)
    (* PRESERVE *)
    (* altera_attribute = "-name SYNCHRONIZER_IDENTIFICATION \"FORCED IF ASYNCHRONOUS\"" *)

    reg sync_reg [DEPTH-1:0];

    integer i;

    initial begin
        for(i=0; i < DEPTH; i=i+1) begin
            sync_reg [i] = 1'b0;
        end
    end
</pre>

<p>Pass the bit through DEPTH registers into the receiving clock domain.
 Peel out the first iteration to avoid a -1 index.</p>

<pre>
    always @(posedge receiving_clock) begin
        sync_reg [0] <= bit_in;

        for(i = 1; i < DEPTH; i = i+1) begin: cdc_stages
            sync_reg [i] <= sync_reg [i-1]; 
        end
    end

    always @(*) begin
        bit_out = sync_reg [DEPTH-1];
    end

endmodule
</pre>

<hr>
<p><a href="./index.html">Back to FPGA Design Elements</a>
<center><a href="https://fpgacpu.ca/">fpgacpu.ca</a></center>
</body>
</html>

